package com.android.djlmapp.tools.facetools;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.Log;

import com.android.djlmapp.R;
import com.android.djlmapp.application.MyApplication;
import com.android.djlmapp.dialog.MyUsualyDialogggg;
import com.android.djlmapp.listener.face.FaceResultBackListener;
import com.android.djlmapp.listener.read.GetPhotoUrlListener;
import com.android.djlmapp.model.eventbus.FaceRzInfo;
import com.android.djlmapp.model.home.Info;
import com.android.djlmapp.tools.global.ConstantsValue;
import com.android.djlmapp.tools.global.PrefUtils;
import com.android.djlmapp.tools.global.ToastUtils;
import com.android.djlmapp.tools.read.GetPhotoUrlUtils;
import com.android.readcard.dialog.MyUsualyDialog;
import com.android.readcard.eventbus.Event;
import com.android.readcard.eventbus.EventBusUtil;
import com.android.readcard.eventbus.EventCodes;
import com.android.readcard.utils.ImageTools;
import com.google.gson.Gson;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import com.lzy.okgo.callback.StringCallback;
import com.lzy.okgo.model.Response;
import com.megvii.licensemanager.Manager;
import com.megvii.livenessdetection.LivenessLicenseManager;
import com.megvii.livenesslib.LivenessActivity;
import com.megvii.livenesslib.OpenActiviyuCallBackListener;
import com.megvii.livenesslib.util.ConUtil;

import org.apache.http.Header;
import org.json.JSONObject;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.Calendar;
import java.util.Locale;
import java.util.Map;

/**
 * 人脸识别 ，活体检测 调用方法
 */

public class FaceUtils {
    public static final int LIVENESS_CODE = 1001; // 活体检测
    public static final int LIVENESS_CODE3 = 1012;// 静态检测
    private String uuid = "";
    private String cardPhotoUrl = "";
    private String mRealName = "";
    private String mIDCardNum = "";
    private String headPath = "";
    private Activity mContext;
    private MyUsualyDialogggg mProgressDialogggg;
    private final MyUsualyDialog mProgressDialog;

    private String isShiMing = "";// 0是单纯实名认证,1是提交订单活体检测
    private Boolean shouQuanFlag = false; // 是否授权成功
    private FaceResultBackListener mFaceResultBackListener;
    Handler mHandler_Init = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1) {
                //成功
                shouQuanFlag = true;
            } else {
                shouQuanFlag = false;
                //联网授权失败！请检查网络或找服务商
            }
        }
    };

    /**
     * @param context
     * @param isShiMing    0是单纯实名认证,1是提交订单活体检测
     * @param cardPhotoUrl 身份证头像连接
     * @param idcard       身份证号码
     * @param headPath     身份证路径
     * @param realName     姓名
     */
    public FaceUtils(Activity context, String isShiMing, String realName,
                     String idcard, String headPath, String cardPhotoUrl,
                     FaceResultBackListener mFaceResultBackListener) {
        this.mContext = context;
        this.isShiMing = isShiMing;
        this.cardPhotoUrl = cardPhotoUrl;
        this.mIDCardNum = idcard;
        this.headPath = headPath;
        this.mFaceResultBackListener = mFaceResultBackListener;
        mRealName = realName;
        mProgressDialogggg = new MyUsualyDialogggg(mContext);
        mProgressDialogggg.setCanceledOnTouchOutside(false);

        mProgressDialog = new MyUsualyDialog(mContext, R.layout.wait_item);
        mProgressDialog.setCancelable(false);
        mProgressDialog.setCanceledOnTouchOutside(false);
    }

    /**
     * 在活体检测前先调用联网授权,然后在要启动的时候调用isShouQuan()判断是否成功
     */
    public void netWorkWarranty() {
        uuid = ConUtil.getUUIDString(mContext);
        new Thread(new Runnable() {
            @Override
            public void run() {
                Manager manager = new Manager(mContext);
                LivenessLicenseManager licenseManager = new LivenessLicenseManager(mContext);
                manager.registerLicenseManager(licenseManager);

                manager.takeLicenseFromNetwork(uuid);
                if (licenseManager.checkCachedLicense() > 0) {
                    mHandler_Init.sendEmptyMessageDelayed(1, 500);
                } else {
                    mHandler_Init.sendEmptyMessageDelayed(2, 500);
                }
            }
        }).start();
    }

    /**
     * 如果mContext的onActivityResult返回的结果是1就关闭界面
     */
    public void jumpActivity() {
        Intent intent = new Intent(mContext, LivenessActivity.class);
        LivenessActivity.setCallBackListener(mCallBack);
        mContext.startActivityForResult(intent, LIVENESS_CODE);
    }

    /**
     * 是否授权成功
     *
     * @return
     */
    public Boolean isShouQuan() {
        return shouQuanFlag;
    }

    OpenActiviyuCallBackListener mCallBack = new OpenActiviyuCallBackListener() {
        @Override
        public void callBack(final Bitmap bmp, String delta, Map<String, byte[]> images) {
//            showProgressDialog("正在验证...");
            Log.e("活体检测", "活体检测成功!!! called with: bmp = [" + bmp != null ?
                    "成功" : "失败" + "], delta = [" + delta != null ? "成功" : "失败"
                    + "], images = [" + images != null ? "成功" : "失败" + "]");

            // 保存活体检测图片
            saveFacePhoto(bmp, cardPhotoUrl, mIDCardNum, delta, images);
        }

        @Override
        public void error(String message) {
            Log.e("活体检测", "活体检测失败!!! called with: message = [" + message + "]");
            sucJump(false,  message);
        }

        @Override
        public void finish() {
            Log.e("活体检测", "活体检测结束!!!");
        }
    };

    /**
     * 保存活体检测最佳图片
     *
     * @param bitmap
     * @param cardPhotoUrl
     * @param cardID
     * @param delta
     * @param images
     */
    private void saveFacePhoto(Bitmap bitmap, String cardPhotoUrl, String cardID,
                               String delta, Map<String, byte[]> images) {
        if (bitmap == null) {
            sucJump(false,  "上传的文件对象不能为空！");
            return;
        }
        if (cardPhotoUrl == null || cardPhotoUrl.trim().length() == 0) {
            sucJump(false,  "身份证图片不能为空！");
            return;
        }
        if (delta == null || delta.trim().length() == 0) {
            sucJump(false,  "活体检测校验码不能为空！");
            return;
        }
        if (cardID == null || cardID.trim().length() < 15) {
            sucJump(false,  "身份证号码有误");
            return;
        }
        if (images == null || images.size() == 0) {
            sucJump(false,  "活体检测图片集合不能为空！");
            return;
        }

        mProgressDialog.show();
        new Thread(new Runnable() {
            @Override
            public void run() {
                String name = DateFormat.format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";
                File file = ImageTools.savePhotoToSDCard(bitmap, Environment.getExternalStorageDirectory()
                        + "/CompressImageUtils/", name);
                bitmap.recycle();
                GetPhotoUrlUtils.getPhotoUrl(file.getPath(), new GetPhotoUrlListener() {
                    @Override
                    public void backPhotoUrl(int backType, String photoUrl) {
                        if (backType == 1) {
                            nameSureParallel(delta, images, photoUrl);
                        } else {
                            mProgressDialog.dismiss();
                            sucJump(false, "活体检测头像:" + photoUrl);
                        }
                    }
                });
            }
        }).start();
    }

    /**
     * 开始活体检测对比
     */
    private void nameSureParallel(String delta, Map<String, byte[]> images, String photoUrl) {
        Log.e("项目异常", mIDCardNum + "------nameSureParallel------" + headPath);

        try {
            RequestParams requestParams = new RequestParams();
            requestParams.put("uuid", uuid);
            requestParams.put("image_ref1", new FileInputStream(new File(
                    headPath)));// 传入身份证头像照片路径
            requestParams.put("delta", delta);
            requestParams.put("api_key", "iOzZNlHB2fsz_Bj_3_C2GN5vOdLIoNBc");
            requestParams.put("api_secret", "G3Dliy_up17PCxP6Z_sc3VTlNQSl7v_X");
            requestParams.put("comparison_type", 0 + "");
            requestParams.put("face_image_type", "meglive");

            for (Map.Entry<String, byte[]> entry : images.entrySet()) {
                ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(entry.getValue());
                requestParams.put(entry.getKey(), byteArrayInputStream);
            }
            AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
            String url = "https://api.megvii.com/faceid/v2/verify";
            asyncHttpClient.post(url, requestParams,
                    new AsyncHttpResponseHandler() {
                        @Override
                        public void onSuccess(int i, Header[] headers, byte[] bytes) {
                            mProgressDialog.dismiss();
                            String successStr = new String(bytes);
                            JSONObject jsonObject;
                            try {

                                jsonObject = new JSONObject(successStr);
                                if (!successStr.contains("error_message")) {
                                    // 活体最好的一张照片和拍摄身份证上的照片的比较
                                    JSONObject jObject = jsonObject
                                            .getJSONObject("result_ref1");
                                    double idcard_confidence = jObject
                                            .getDouble("confidence");
                                    double idcard_threshold = jObject
                                            .getJSONObject("thresholds")
                                            .getDouble("1e-3");
                                    double idcard_tenThreshold = jObject
                                            .getJSONObject("thresholds")
                                            .getDouble("1e-4");
                                    double idcard_hundredThreshold = jObject
                                            .getJSONObject("thresholds")
                                            .getDouble("1e-5");

                                    // 解析faceGen
                                    JSONObject jObject1 = jsonObject
                                            .getJSONObject("face_genuineness");

                                    float mask_confidence = (float) jObject1
                                            .getDouble("mask_confidence");
                                    float mask_threshold = (float) jObject1
                                            .getDouble("mask_threshold");
                                    float screen_replay_confidence = (float) jObject1
                                            .getDouble("screen_replay_confidence");
                                    float screen_replay_threshold = (float) jObject1
                                            .getDouble("screen_replay_threshold");

                                    float synthetic_face_confidence = (float) jObject1
                                            .getDouble("synthetic_face_confidence");
                                    float synthetic_face_threshold = (float) jObject1
                                            .getDouble("synthetic_face_threshold");
                                    int face_replaced = jObject1.getInt("face_replaced");

                                    if (mask_confidence >= 0.2) {
                                        ToastUtils.showShortToast(mContext, "面具攻击，识别不通过！");
                                        mProgressDialogggg = new MyUsualyDialogggg(mContext);
                                        mProgressDialogggg.setCanceledOnTouchOutside(false);
                                        mProgressDialogggg.show();
                                    } else if (screen_replay_confidence >= 0.2) {
                                        ToastUtils.showShortToast(mContext, "屏幕翻拍，识别不通过！");
                                        mProgressDialogggg = new MyUsualyDialogggg(mContext);
                                        mProgressDialogggg.setCanceledOnTouchOutside(false);
                                        mProgressDialogggg.show();
                                    } else if (synthetic_face_confidence >= 0.2) {
                                        ToastUtils.showShortToast(mContext, "软件合成，识别不通过！");
                                        mProgressDialogggg = new MyUsualyDialogggg(mContext);
                                        mProgressDialogggg.setCanceledOnTouchOutside(false);
                                        mProgressDialogggg.show();
                                    } else if (face_replaced == 1) { // 0表示未检测出换脸攻击，1表示检测出了换脸攻击
                                        mProgressDialogggg = new MyUsualyDialogggg(mContext);
                                        mProgressDialogggg.setCanceledOnTouchOutside(false);
                                        mProgressDialogggg.show();
                                    } else {
                                        if (idcard_confidence >= idcard_tenThreshold) {
                                            comperSucces(photoUrl);
                                        } else {
                                            mProgressDialog.dismiss();
                                            ToastUtils.showShortToast(mContext, "识别未通过，请重新验证！");
                                            mProgressDialogggg = new MyUsualyDialogggg(mContext);
                                            mProgressDialogggg.setCanceledOnTouchOutside(false);
                                            mProgressDialogggg.setCancelable(false);
                                            mProgressDialogggg.show();
                                        }
                                    }
                                } else {
                                    String error_message = jsonObject.getString("error_message");
                                    mProgressDialog.dismiss();
                                    sucJump(false,  error_message);
                                }
                            } catch (Exception e1) {
                                e1.printStackTrace();
                                Log.e("项目异常", "------请重新识别e1------" + e1.toString());
                                mProgressDialog.dismiss();
                                sucJump(false,"数据解析异常,验证失败，请重新验证");
                            }
                        }

                        @Override
                        public void onFailure(int i, Header[] headers,
                                              byte[] bytes, Throwable throwable) {
                            Log.e("项目异常", "------请重新识别e2------" + throwable.toString());
                            mProgressDialog.dismiss();
                            sucJump(false,"网络异常，请重新识别");
                        }
                    });

        } catch (Exception e) {
            e.printStackTrace();
            mProgressDialog.dismiss();
            sucJump(false,  "活体检测失败e");
        }

    }

    /**
     * 活体检测成功,根据isShiMing判断是直接跳转还是继续去接口实名对比
     *
     * @param photoUrl
     */
    private void comperSucces(String photoUrl) {
        if (!"0".equals(isShiMing)) {
            new Thread() {
                @Override
                public void run() {
                    super.run();

                    // 人脸对比成功后清空存储的图片
                    ImageTools.deleteAllPhoto(mContext, Environment.getExternalStorageDirectory()
                            + "/CompressImageUtils/");
                    ImageTools.deleteAllPhoto(mContext, Environment.getExternalStorageDirectory()
                            + "/wltlib/");

                    FaceRzInfo faceRzInfo = new FaceRzInfo();
                    faceRzInfo.setFace_image(photoUrl); // 人脸识别照片
                    faceRzInfo.setFace_ok("1"); // 认证结果 1 成功  2 失败
                    faceRzInfo.setSfz_card(mIDCardNum);
                    faceRzInfo.setSfz_name(mRealName);
                    faceRzInfo.setSfzPhoto(cardPhotoUrl); // 身份证头像
                    Event<FaceRzInfo> event = new Event<>(EventCodes.EventFaceCode.A, faceRzInfo);
                    EventBusUtil.sendEvent(event);
                }
            }.start();
            sucJump(true,  "");
        } else {
            // 如果是实名认证还需要接口对比将身份头像和活体图片传上去
            shiMingParallel(photoUrl);
        }
    }

    /**
     * 实名对比
     *
     * @param photoUrl
     */
    private void shiMingParallel(String photoUrl) {
        String mobile = PrefUtils.getString(ConstantsValue.BD_MOBILE, "");
        MyApplication.getInstance().getHttpTools().ShiMingDuiBi(mIDCardNum, cardPhotoUrl,
                photoUrl, mobile, new StringCallback() {
                    @Override
                    public void onSuccess(Response<String> response) {
                        try {
                            Gson gson = new Gson();
                            Info smrzInfo = gson.fromJson(response.body(), Info.class);
                            if (smrzInfo != null) {
                                int code = smrzInfo.getCode();
                                if (code < 1000) {
                                    sucJump(true, "");
                                } else {
                                    sucJump(false,  "SMRZ" + smrzInfo.getMsg());
                                }
                            } else {
                                sucJump(false,  "SMRZ服务器返回数据为空");
                            }
                        } catch (Exception e) {
                            sucJump(false,  "SMRZ数据解析异常");
                        }
                    }

                    @Override
                    public void onError(Response<String> response) {
                        super.onError(response);
                        sucJump(false, "SMRZ网络或服务器错误");
                    }
                });

    }

    /**
     * @param sucFlag 是否成功
     * @param errMsg  错误信息,成功传空值""就行
     */
    private void sucJump(boolean sucFlag, String errMsg) {
        int backCode;// 1代表成功,2代表失败
        mProgressDialog.dismiss();
        if (sucFlag) {
            PrefUtils.putString("BD_SMRZ", "1"); // 实名认证
            backCode = 1;
        } else {
            backCode = 2;
            if (!TextUtils.isEmpty(errMsg)) {
                ToastUtils.showShortToast(mContext, errMsg);
            }
        }
        mFaceResultBackListener.backCode(backCode);
    }
}
